package model.dominio;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.PostPersist;
import javax.persistence.PostUpdate;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import model.dao.DaoBase;

/**
 * 
 * @author Daniel
 * Classe responsável pelos objetos de cada Tipo de Veículo.
 * Mapeamento relacionado ao Hibernate efetuado abaixo.
 */
@Entity
@Table(name = "tipo_veiculo")
public class TipoVeiculo implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(unique = true, nullable = false)
    private Integer codigo = 0;
    @Column(length = 100)
    private String tipo;
    @Column
    private double precoBase;
    @Column
    private double precoKm;
    @Column
    private double taxaUnica;
    @OneToMany(mappedBy = "tipo")
    private List<Veiculo> veiculos = new ArrayList<Veiculo>();
    @Temporal(TemporalType.TIMESTAMP)
    private Calendar data_ultima_alteracao;
    @JoinColumn(name = "codigo_usuario", referencedColumnName = "codigo")
    @ManyToOne(optional = true, fetch = FetchType.EAGER, cascade = CascadeType.PERSIST)
    private Usuario usuario;

    /**
     * Construtor básico de objetos da classe.
     * Utilizado para...
     */
    public TipoVeiculo() {
    }

    /**
     * Construtor secundário de objetos da classe. Exige:
     * @param tipo 
     * Informação obrigatória para criação de um novo Tipo de Veículo.
     */
    public TipoVeiculo(String tipo) {
        this.tipo = tipo;
    }

    /**
     * Construtor secundário de objetos da classe. Exige:
     * @param tipo
     * @param precoBase
     * @param precoKm
     * @param taxaUnica 
     * Além da informação obrigatória, complementa os dados do Tipo de Veículo.
     */
    public TipoVeiculo(String tipo, double precoBase, double precoKm, double taxaUnica) {
        this.precoBase = precoBase;
        this.precoKm = precoKm;
        this.tipo = tipo;
        this.taxaUnica = taxaUnica;
    }

    /**
     * @param codigo the codigo to set
     */
    public void setCodigo(Integer codigo) {
        this.codigo = codigo;
    }

    /**
     * @param preco 
     */
    public void setPBase(double preco) {
        this.precoBase = preco;
    }

    /**
     * @param preco 
     */
    public void setPKm(double preco) {
        this.precoKm = preco;
    }

    /**
     * @return codigo do Tipo de Veículo
     */
    public int getCodigo() {
        return this.codigo;
    }

    /**
     * @return precoBase de um Tipo de Veículo
     */
    public double getPrecoBase() {
        return this.precoBase;
    }

    /**
     * @return preçoKM de um Tipo de Veículo
     */
    public double getPrecoKm() {
        return this.precoKm;
    }

    /**
     * @return Tipo de Veículo
     */
    public String getTipo() {
        return this.tipo;
    }

    /**
     * @param tipo 
     */
    public void setTipo(String tipo) {
        this.tipo = tipo;
    }

    /**
     * @return taxaUnica de cada Tipo de Veículo
     */
    public double getTaxaUnica() {
        return taxaUnica;
    }

    /**
     * @param taxaUnica
     */
    public void setTaxaUnica(double taxaUnica) {
        this.taxaUnica = taxaUnica;
    }

    /**
     * Sobrescrita do método toString()
     * @return Tipo de Veículo
     */
    @Override
    public String toString() {
        return this.getTipo();
    }

    /**
     * @return the veiculos
     */
    public List<Veiculo> getVeiculos() {
        return veiculos;
    }

    /**
     * Sobrescrita do método equals()
     * @param obj
     * Verificação se objeto é da classe TipoVeiculo
     * @return Tipo de Veículo
     * Usado para comparação durante a busca
     */
    @Override
    public boolean equals(Object obj) {
        if (obj instanceof TipoVeiculo) {
            TipoVeiculo t = (TipoVeiculo) obj;
            return this.getTipo().equals(t.getTipo());
        } else {
            return false;
        }
    }

    public Calendar getData_ultima_alteracao() {
        return this.data_ultima_alteracao;
    }

    public void setData_ultima_alteracao(Calendar data_ultima_alteracao) {
        this.data_ultima_alteracao = data_ultima_alteracao;
    }

    public void setUsuario(Usuario usuarioLogado) {
        this.usuario = usuarioLogado;
    }

    public Usuario getUsuario() {
        return this.usuario;
    }

    @PostPersist
    public void gerarLogCad() {
        Logg logg = new Logg();
        logg.setCodigo_objeto(this.codigo);
        logg.setAcao(new AcaoSistema(15));
        logg.setData_hora(this.data_ultima_alteracao);
        logg.setUsuario(this.usuario);
        new DaoBase().salvar(logg);
    }

    @PostUpdate
    public void gerarLogAlt() {
        Logg logg = new Logg();
        logg.setCodigo_objeto(this.codigo);
        logg.setAcao(new AcaoSistema(16));
        logg.setData_hora(this.data_ultima_alteracao);
        logg.setUsuario(this.usuario);
        new DaoBase().salvar(logg);
    }
}